/*
 * CS_REQ_DAILY_MISSION_REWARD.cpp
 *
 *  Created on: 2014. 4. 10.
 *      Author: mega
 */

#include "../../User.h"
#include "../../Command.h"
#include "../../NLogic/DailyMission.h"
#include "../../NResource/Static.h"

namespace ProjectZ { namespace NCommand {

static void SendFailDailyMissionReward(User * pUser, int ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_REQ_DAILY_MISSION_REWARD);
	pUser->Send(pAck);
}

bool SendItemMail(User * pUser, NResource::DailyMissionResource::Flyweight * pFly)
{
	NLogic::MailBox::Mail::Data clsMailData;
	clsMailData.send_user_seq		= 0;
	clsMailData.send_user_nickname	= "GAMEVIL";
	clsMailData.recv_user_seq		= pUser->GetUserSeq();
	clsMailData.message				= NResource::Static::InstancePtr()->GetMailMessageResource()->GetMessageDailyMissionReward();
	clsMailData.gift_status			= EM_GIFT_ITEM;

	NLogic::Item::Data clsItemData;
	clsItemData.tid			= pFly->_ITEM_TID;
	clsItemData.sub_type	= pFly->_ITEM_SHEET;
	clsItemData.class_type	= pFly->_ITEM_CLASS;

	int isStack = NResource::Static::InstancePtr()->GetItemResource()->getItemStackType(clsItemData);

	int sendMailCount	= 0;
	int itemQuantity	= 0;

	// 스택 아이템이 아니면서, 보상 수량이 2개 이상인 경우는 아이템을 하나씩 첨부하여 메일을 각각 발송한다.
	if (1 != isStack && pFly->_VALUE >= 2)
	{
		itemQuantity	= 1;
		sendMailCount	= pFly->_VALUE;
	}
	else
	{
		itemQuantity	= pFly->_VALUE;
		sendMailCount	= 1;
	}

	if (false == NResource::Static::InstancePtr()->GetItemResource()->SetItemFromXLS(pUser, clsMailData.item, pFly->_ITEM_SHEET, pFly->_ITEM_TID, itemQuantity))
	{
		DEBUGLOG("%s : Item Setting Fail", __FUNCTION__);
		SendFailDailyMissionReward(pUser, ACK_UNKNOWN_ERROR);
		return false;
	}

	for (int i = 0; i < sendMailCount; i++)
	{
		if (false == NLogic::NFunction::SendMail(pUser, clsMailData))
		{
			DEBUGLOG("%s : Item Mail Send Fail", __FUNCTION__);
			SendFailDailyMissionReward(pUser, ACK_DB_ERROR);
			return false;
		}
	}

	return true;
}

bool SendGoldMail(User * pUser, NResource::DailyMissionResource::Flyweight * pFly)
{
	NLogic::MailBox::Mail::Data clsMailData;
	clsMailData.send_user_seq		= 0;
	clsMailData.send_user_nickname	= "GAMEVIL";
	clsMailData.recv_user_seq		= pUser->GetUserSeq();
	clsMailData.message				= NResource::Static::InstancePtr()->GetMailMessageResource()->GetMessageDailyMissionReward();
	clsMailData.gift_status			= EM_GIFT_GOLD;
	clsMailData.gold				= pFly->_VALUE;

	if (false == NLogic::NFunction::SendMail(pUser, clsMailData))
	{
		DEBUGLOG("%s : GOLD Mail Send Fail!!", __FUNCTION__);
		SendFailDailyMissionReward(pUser, ACK_DB_ERROR);
		return false;
	}

	return true;
}

void Command::CS_REQ_DAILY_MISSION_REWARD(User * pUser, ::Network::Packet * pPacket)
{
/*	CS_REQ_DAILY_MISSION_REWARD			0x0962
	{
		u16 u16mission_idx;		/// 일일미션 테이블 아이디
	}

	SC_REQ_DAILY_MISSION_REWARD			0x0963
	{
		s16 s16ack;
		u16 u16mission_idx;		/// 일일미션 테이블 아이디
	}*/

	PREPARE_PACKET;

	if (false == NResource::Static::Instance().GetContentsOpenResource()->IsOpen(static_cast<int>(ContentsOpen::DAILY_MISSION)))
	{
		DEBUGLOG("%s : Contents is Not Open", __FUNCTION__);
		SendFailDailyMissionReward(pUser, ACK_NOT_OPEN);
		return;
	}

	uint16_t missionType = 0;

	*pPacket >> missionType;

	if (static_cast<int>(NLogic::DailyMission::MissionType::SPECIAL_MISSION) > missionType)
	{
		DEBUGLOG("%s : INVALID TYPE. MissionType=%d", __FUNCTION__, missionType);
		SendFailDailyMissionReward(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (static_cast<int>(NLogic::DailyMission::MissionType::__MAX__) - 1 < missionType)
	{
		DEBUGLOG("%s : INVALID TYPE. MissionType=%d", __FUNCTION__, missionType);
		SendFailDailyMissionReward(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::DailyMission * pDailyMission = pUser->GetDailyMission();
	if (NULL == pDailyMission)
	{
		DEBUGLOG("%s : pDailyMission is NULL", __FUNCTION__);
		SendFailDailyMissionReward(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::DailyMission::Data * pMissionData = pDailyMission->GetData(static_cast<NLogic::DailyMission::MissionType>(missionType));
	if (NULL == pMissionData)
	{
		DEBUGLOG("%s : pMissionData is NULL. MissionType=%d", __FUNCTION__, missionType);
		SendFailDailyMissionReward(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 보상 수령 가능 상태가 아닌 경우
	if (1 != pMissionData->isReward)
	{
		DEBUGLOG("%s : NOT RECV REWARD. MissionType=%d", __FUNCTION__, missionType);
		SendFailDailyMissionReward(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NResource::DailyMissionResource::Flyweight * pFly = NResource::Static::Instance().GetDailyMissionResource()->GetFly(missionType);
	if (NULL == pFly)
	{
		DEBUGLOG("%s : pFly is NULL", __FUNCTION__);
		SendFailDailyMissionReward(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (0 == pFly->_KIND)		// 아이템
	{
		if (false == SendItemMail(pUser, pFly))
			return;
	}
	else if (1 == pFly->_KIND)	// 골드
	{
		if (false == SendGoldMail(pUser, pFly))
			return;
	}
	else if (2 == pFly->_KIND)	// 경험치
	{
		int rewardExp = static_cast<int>((pUser->GetCharacterInfo().level * pFly->_VALUE * sqrt(pUser->GetCharacterInfo().level) ) / 150) * 100;
		NLogic::NFunction::IncreaseExp(pUser, rewardExp);
	}
	else if (3 == pFly->_KIND) // 스태미너 (중국)
	{
		int cur_stamina = pUser->GetCharacterInfo().cur_stamina + pFly->_VALUE;
		if (cur_stamina >= STAMINA_MAX_CHARGE)
		{
			SendFailDailyMissionReward(pUser, ACK_STAMINA_MAX_OVERFLOW);
			return;
		}

		pUser->GetCharacterInfo().cur_stamina = cur_stamina;
	}
	else
	{
		DEBUGLOG("%s : INVALID REWARD KIND=%d", __FUNCTION__, pFly->_KIND);
		SendFailDailyMissionReward(pUser, ACK_DB_ERROR);
		return;
	}

	// 응답
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(ACK_OK) << missionType;
	pAck->MakePacket(CMD_SC_REQ_DAILY_MISSION_REWARD);
	pUser->Send(pAck);

	// 보상 수령 상태로 변경
	pMissionData->isReward = 2;
}

} /*NCommand*/ } /*ProjectZ*/
